<template>
  <div class="date-box-body">
    <div class="days-row" v-for="(row, index) in rows" :key="index">
      <div
        :class="[
          'date-picker-item',
          item.type === 'normal' || item.type === 'today'
            ? 'date-picker-item-normal'
            : 'date-picker-item-innormal',
          item.selected && (item.type === 'normal' || item.type === 'today')
            ? 'date-picker-item-selected'
            : '',
        ]"
        v-for="item in row"
        :key="item.column"
        @click="handleCheckDay(item.type, item.text)"
      >
        {{ item.text }}
      </div>
    </div>
  </div>
</template>

<script>
import {
  getFirstDayOfMonth,
  getDayCountOfMonth,
  getStartDateOfMonth,
  nextDate,
  clearTime as _clearTime,
} from '../../utils/date-util';

const getDateTimestamp = function (time) {
  if (typeof time === 'number' || typeof time === 'string') {
    return _clearTime(new Date(time)).getTime();
  } else if (time instanceof Date) {
    return _clearTime(time).getTime();
  } else {
    return NaN;
  }
};

export default {
  name: 'DateTable',
  props: {
    // 上侧显示的日历日期
    calendarDate: {
      type: String,
      required: true,
    },
    // 选中的日期(选中渲染)
    selectedDate: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      tableRows: [[], [], [], [], [], []],
    };
  },
  computed: {
    dateValue() {
      return new Date(this.calendarDate + ' 00:00'); // yyyy-mm-dd格式 会自动+8
    },
    year() {
      return this.dateValue.getFullYear();
    },
    month() {
      // 0~11
      return this.dateValue.getMonth();
    },
    showMonth() {
      const mm = this.dateValue.getMonth() + 1;
      return mm > 9 ? mm.toString() : '0' + mm;
    },
    startDate() {
      return getStartDateOfMonth(this.year, this.month);
    },
    rows() {
      const date = new Date(this.year, this.month, 1);
      let day = getFirstDayOfMonth(date); // day of first day
      const dateCountOfMonth = getDayCountOfMonth(
        date.getFullYear(),
        date.getMonth()
      );
      const dateCountOfLastMonth = getDayCountOfMonth(
        date.getFullYear(),
        date.getMonth() === 0 ? 11 : date.getMonth() - 1
      );
      day = day === 0 ? 7 : day;

      const offset = 0;
      const rows = this.tableRows;
      let count = 1;

      const startDate = this.startDate;
      const now = getDateTimestamp(new Date());
      const selectedTime = new Date(this.selectedDate + ' 00:00').getTime();
      for (let i = 0; i < 6; i++) {
        const row = rows[i];

        for (let j = 0; j < 7; j++) {
          let cell = row[j];
          if (!cell) {
            cell = {
              row: i,
              column: j,
              type: 'normal',
              inRange: false,
              start: false,
              end: false,
            };
          }

          cell.type = 'normal';

          const index = i * 7 + j;
          const time = nextDate(startDate, index - offset).getTime();
          cell.inRange =
            time >= getDateTimestamp(this.minDate) &&
            time <= getDateTimestamp(this.maxDate);
          cell.start = this.minDate && time === getDateTimestamp(this.minDate);
          cell.end = this.maxDate && time === getDateTimestamp(this.maxDate);
          const isToday = time === now;

          if (isToday) {
            cell.type = 'today';
          }

          if (i >= 0 && i <= 1) {
            const numberOfDaysFromPreviousMonth =
              day + offset < 0 ? 7 + day + offset : day + offset;

            if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
              cell.text = count++;
            } else {
              cell.text =
                dateCountOfLastMonth -
                (numberOfDaysFromPreviousMonth - (j % 7)) +
                1 +
                i * 7;
              cell.type = 'prev-month';
            }
          } else {
            if (count <= dateCountOfMonth) {
              cell.text = count++;
            } else {
              cell.text = count++ - dateCountOfMonth;
              cell.type = 'next-month';
            }
          }
          let cellDate = new Date(time);
          cell.selected = selectedTime === cellDate.getTime();
          this.$set(row, j, cell);
        }
      }
      return rows;
    },
  },
  created() {},
  methods: {
    // 选中日期
    handleCheckDay(type, day) {
      const newDay = day > 9 ? day : '0' + day;
      let year = this.year;
      let month = this.showMonth;
      if (type === 'prev-month') {
        if (this.showMonth === '01') {
          year -= 1;
          month = '12';
        } else {
          month = this.month > 9 ? this.month : '0' + this.month;
        }
      } else if (type === 'next-month') {
        if (this.showMonth === '12') {
          year += 1;
          month = '01';
        } else {
          const mon = this.month + 2;
          month = mon > 9 ? mon : '0' + mon;
        }
      }
      const newDate = year + '-' + month + '-' + newDay;
      this.$emit('onSelectDay', newDate);
    },
  },
};
</script>

<style lang="scss" scoped></style>
